import java.util.*;

public class BadugiStol 
{
	ArrayList<BadugiGracz> gracze;
	BadugiTalia talia;
	BadugiDecyzja d;
	Scanner sc = new Scanner(System.in);
	Random rnd = new Random();
	private Scanner pieniadze;
	BadugiGracz losowyGracz, zaczynaGracz, zwyciezca, smallBlindGracz, bigBlindGracz;
	
	public static boolean dealerButton = false, smallBlind = false, bigBlind = false;
	int AllIn = 0, bet = 0, stawka = 0;
	public static int bank, wpisoweSmallBlind, wpisoweBigBlind, numerLicytacji;
	
	public BadugiStol(int iloscGraczy, int iloscBotow)
	{
		gracze = new ArrayList<>();
		talia = new BadugiTalia();
		
		while (iloscGraczy-- > 0)
		{
			dodajGracza(new BadugiCzlowiek("Gracz "+ (iloscGraczy+1)));
		}
		while (iloscBotow-- > 0)
		{
			dodajGracza(new BadugiBot("Gracz "+ (iloscGraczy+1)));
		}
	}
	
	final void dodajGracza(final BadugiGracz g)
	{
		if (gracze.size() < 6)
		{
			gracze.add(g);
		}
	}
	
	final void rozdajKarty()
	{
		for (BadugiGracz g : gracze)
		{
			g.reka = talia.losujReke();
		}
	}
	
	final void dobierzKartyGraczowi(final ArrayList<BadugiKarta> kartyDoWymiany, final BadugiGracz g)
	{
		g.reka.usunKarty(kartyDoWymiany);
		int iloscKartDoWymiany = kartyDoWymiany.size();
		while (iloscKartDoWymiany-- > 0)
		{
			g.reka.dodajKarte(talia.losujKarte());
		}
		talia.dodajKarty(kartyDoWymiany);
	}
	
	final BadugiGracz ustalZwyciezce()
	{
		Collections.sort(gracze);
		return gracze.get(gracze.size() - 1);
	}
	
	final void wyswietlStol()
	{
		for (BadugiGracz g : gracze)
		{
			System.out.print(g + ": ");
			System.out.print(g.reka);
            System.out.println("  = " + g.reka.pobierzUklad());
        }
	}
	
	void rozdajZetony() throws Exception 
	{
		try {
				System.out.println("Podaj startowa ilosc zetonow graczy (wieksza od 0)");
				pieniadze = new Scanner(System.in);
				
				int suma_zetonow = pieniadze.nextInt();
				if (suma_zetonow <= 0)  
				{
					System.out.println("Ilosc zetonow musi byc wieksza od 0 ! Sprobuj ponownie...");
					pieniadze = new Scanner(System.in);
					suma_zetonow = pieniadze.nextInt();
				}
				
				for (BadugiGracz obecnyGracz : gracze) 
				{	
					obecnyGracz.zetony = suma_zetonow ;		
				}

			}
			catch (InputMismatchException f) {
				System.out.println("Sprobuj ponownie!");
				rozdajZetony();
			}
	}
	
	void podliczenieZetonow()
	{
	/*
		for (BadugiGracz obecnyGracz : gracze)  
		{
			if (flag == false) { 
				if (obecnyGracz == zwyciezca) 
				{
					obecnyGracz.zetony += bank;
				}
			}
			else  //jesli gracz wchodzil All-In
			{
				if (obecnyGracz == zwyciezca) {
					if (bank < (gracze.size() * AllIn)) { //jesli w banku jest mniej niz ilosc_graczy*wklad-allIn pieniedzy, gracz zbiera cala pule
						obecnyGracz.zetony += bank ;
					} //jesli w banku jest wiecej pieniedzy niz wklad all-In przemnozony przez liczbe uczestnikow, gracz zbiera od kazdego gracza tylko rownowartosc swojego wkladu
					else
					{
						obecnyGracz.zetony += (gracze.size() * AllIn);
					}
				}	
			}
		}
	*/
	}
	
	void losujDealerButton()
	{
		losowyGracz = gracze.get(rnd.nextInt(gracze.size()));
		losowyGracz.dealerButton = true;
		System.out.println(losowyGracz + " ma dealer button");
	}
	
	void przypiszDealerButton()
	{
		for (ListIterator<BadugiGracz> i = gracze.listIterator(); i.hasNext(); )
		{
			BadugiGracz obecnyGracz = i.next();
			if (obecnyGracz.dealerButton == true)
			{
				System.out.println(obecnyGracz+" mial dealer button");
				obecnyGracz.dealerButton = false;
				System.out.println(obecnyGracz+" juz nie ma dealer button");
				obecnyGracz = i.next();
				obecnyGracz.dealerButton = true;
				System.out.println(obecnyGracz+" ma teraz dealer button");
				obecnyGracz = losowyGracz;
			}
		}
	}
	
	void przypiszCiemne()
	{
		for (ListIterator<BadugiGracz> i = gracze.listIterator(); i.hasNext(); )
		{
			BadugiGracz obecnyGracz = i.next();
			if (obecnyGracz == losowyGracz) {
				obecnyGracz = i.next();
				obecnyGracz.smallBlind = true;
				System.out.println(obecnyGracz+ " ma small blind");
				obecnyGracz = smallBlindGracz;
				obecnyGracz = i.next();
				obecnyGracz.bigBlind = true;
				System.out.println(obecnyGracz+ " ma big blind");
				obecnyGracz = bigBlindGracz;
			}
			
			
		}
	}
	
	
	
	
	void wnoszenieZakladow() throws Exception 
	{ 
		System.out.println("Rozpoczyna sie wnoszenie zakladow. ");
		System.out.println("-----------------------------------------------");
		System.out.println("Okresl wysokosc wpisowego:");
		int wpisowe = sc.nextInt();
		
		if (wpisowe <= 0)  
		{
			System.out.println("Zaklad ma byc wyzszy od 0 ! Sprobuj ponownie...");
			sc = new Scanner(System.in);
			wpisowe = sc.nextInt();
		}
		
		for (Iterator<BadugiGracz> i = gracze.iterator(); i.hasNext(); ) 
		{	
			BadugiGracz obecnyGracz = i.next();
			if (obecnyGracz.zetony >= wpisowe) //spr. czy gracza stac na wpisowe
			{
				if (obecnyGracz.smallBlind == true) 
				{
					obecnyGracz.zetony -= wpisoweSmallBlind;
					bank += wpisoweSmallBlind;
					System.out.println(obecnyGracz+" ma jeszcze "+obecnyGracz.zetony+" zetonow.");
				}
				else if (obecnyGracz.bigBlind == true)
				{
					obecnyGracz.zetony -= wpisoweBigBlind;
					bank += wpisoweBigBlind;
					System.out.println(obecnyGracz+" ma jeszcze "+obecnyGracz.zetony+" zetonow.");
				}
				else
				{
					obecnyGracz.zetony -= wpisowe;
					bank += wpisowe;
					System.out.println(obecnyGracz+" ma jeszcze "+obecnyGracz.zetony+" zetonow.");
				}
			}
			else
			{
				System.out.println(obecnyGracz+ " ma za malo zetonow by kontynuowac gre!");	
				if (gracze.size() == 1) 
				{
					System.out.println("Ostatni gracz odpadl z gry!");
					System.exit(0);
				}
				else
				{
					i.remove();
				}
			}
		}
		System.out.println("Bank zebral "+bank+" zetonow.");
		
		zakladySmallBig();
	}
	
	void zakladySmallBig()
	{
		System.out.println("Podaj startowe wpisowe Small Blind:");
		pieniadze = new Scanner(System.in);
		wpisoweSmallBlind = pieniadze.nextInt();
		
		System.out.println("Podaj startowe wpisowe Big Blind:");
		pieniadze = new Scanner(System.in);
		wpisoweBigBlind = pieniadze.nextInt();
	}
	
	void licytacja(int numerLicytacji)
	{
		this.numerLicytacji = numerLicytacji;
		//zmienne globalne: ktoZaczyna, numerLicytacji
		if (numerLicytacji == 1) 
		{
			bet = 0;
			stawka = 0;
		}
		if (numerLicytacji != 1) 
		{
			przypiszDealerButton();
			przypiszCiemne();
		}
		System.out.println("-----------------------------------------------");
		System.out.println("Trwa" +numerLicytacji+ "tura licytacji.");
		ktoZaczyna();
		
		for (ListIterator<BadugiGracz> i = gracze.listIterator(); i.hasNext(); ) 
		{	
			BadugiGracz obecnyGracz = i.next();
			if (obecnyGracz != zaczynaGracz)
			{
				obecnyGracz = i.next();
			}
			
			if (obecnyGracz instanceof BadugiCzlowiek)
			{
				if (bet == 0) //jesli nie zostala ustanowiona pierwsza stawka licytacji
				{
					System.out.println("Teraz jest kolej: "+obecnyGracz);
					System.out.print("Prosze innych graczy o zamkniecie oczu. Nacisnij dowolny klawisz jesli jestes gotowy.");
					sc.nextLine();
					symulujCzyszczenieEkranu();
					System.out.println("Czas na ruch gracza "+obecnyGracz);
					System.out.println("1. Czekaj.");
					System.out.println("2. Postaw pierwsza stawke w licytacji.");
					System.out.println("3. Pas."); 
					System.out.println("4. Wejdz All-In");
					System.out.println();
					System.out.println("Masz jeszcze "+obecnyGracz.zetony+" zetonow.");
					System.out.println("Aktualna stawka licytacji to: "+bet+ " zetonow.");
					System.out.println("Bank zebral do tej pory "+bank+" zetonow");
					System.out.println("Co chcesz zrobic?");
					try 
					{
						int decyzja = sc.nextInt();
						switch(decyzja)
						{
							case 1:
								break;
							case 2:
							{
								System.out.println("Podaj wysokosc stawki: ");
								stawka = sc.nextInt();

								if (obecnyGracz.zetony >= stawka) 
								{
									bet += stawka;
									
									if (bet <= 0)  
									{
										bet -= stawka;
										System.out.println("Stawka ma byc wyzsza od 0 ! Sprobuj ponownie...");
										sc = new Scanner(System.in);
										bet += sc.nextInt();
									}
									
									obecnyGracz.zetony -= bet;
									bank += bet;
								}
								else
								{
									System.out.println("Nie masz tylu zetonow! Podaj wysokosc stawki: ");
									bet += sc.nextInt();
									obecnyGracz.zetony -= bet;
									bank += bet;
								}
							}
								break;
							case 3:
							{
								if (gracze.size() > 1) {
									i.remove();
								}
								else
								{
									System.out.println("Runda dobiega konca! Zaklady wszystkich graczy zostaja w banku.");
								}
							}
								break;
							case 4: 
							{
								//flag = true;
								AllIn = obecnyGracz.zetony;
								bank += obecnyGracz.zetony;
								obecnyGracz.zetony = 0;
								
								int liczbaPozostalychGraczy = gracze.size() - (int)(gracze.indexOf(obecnyGracz)+1);

								for (int x = 1; x <= liczbaPozostalychGraczy; x++) 
								{
									obecnyGracz = i.next();
								}
							}
								break;
							default: licytacja(1);
								break;
						}
					}
					catch (InputMismatchException f)
					{
						System.out.println("Sprobuj ponownie!");
						licytacja(1);
					}
				}
				else
				{
					if(bet != 0) 
					{
						System.out.println("Teraz jest kolej: " + obecnyGracz);
		                System.out.print("Prosze innych graczy o zamkniecie oczu. Nacinij dowolny klawisz jesli jestes gotowy.");
		                sc.nextLine();
		                symulujCzyszczenieEkranu();
		                System.out.println("Czas na ruch gracza "+obecnyGracz);
		                System.out.println("1. Czekaj.");
		                System.out.println("2. Podbij stawke.");
		                System.out.println("3. Wyrownaj do najwyzszego zakladu.");
		                System.out.println("4. Pas.");  //Pas!
		                System.out.println("5. Wejdz All-In.");
						System.out.println();
						System.out.println("Masz jeszcze "+obecnyGracz.zetony+" zetonow.");
						System.out.println("Aktualna stawka licytacji to: "+bet+ " zetonow.");
						System.out.println("Bank zebral do tej pory "+bank+" zetonow.");
						System.out.println("Co chcesz zrobic?");
						try 
						{
							int decyzja = sc.nextInt();
							switch(decyzja)
							{
								case 1:
									break;
								case 2:
								{
									System.out.println("O ile chcesz podbic stawke?");
									int podbicie = sc.nextInt();
									bet += podbicie;
									
									if (bet <= 0)  
									{
										bet -= podbicie;
										System.out.println("Zaklad ma byc wyzszy od 0 ! Sprobuj ponownie...");
										sc = new Scanner(System.in);
										bet = sc.nextInt();
									}
									
									if (obecnyGracz.zetony >= bet) 
									{
										obecnyGracz.zetony -= bet;
										bank += bet;
									}
									else
									{
										bet -= podbicie;
										System.out.println("Nie masz tylu zetonow! O ile chcesz podbic stawke?");
										bet += sc.nextInt();
										obecnyGracz.zetony -= bet;
										bank += bet;
									}
								}
								case 3:
								{
									if (obecnyGracz.zetony >= bet) 
									{
										obecnyGracz.zetony -= bet ;
										bank += bet;
									}
									else
									{
										System.out.println("Nie masz tylu zetonow! Tracisz kolejke za probe oszustwa!");
									}
								}
									break;
								case 4: 
								{
									if (gracze.size() > 1) {
										i.remove();
									}
									else
									{
										System.out.println("Runda dobiega konca! Zaklady wszystkich graczy zostaja w banku.");
									}
								}
									break;
								case 5:
								{
									//flag = true;
									AllIn = obecnyGracz.zetony;
									bank += obecnyGracz.zetony;
									obecnyGracz.zetony = 0;
									
									int liczbaPozostalychGraczy = gracze.size() - (int)(gracze.indexOf(obecnyGracz)+1);

									for (int x = 1; x <= liczbaPozostalychGraczy; x++) 
									{
										obecnyGracz = i.next();
									}
								}
									break;
								default: licytacja(1);
									break;
							}
						}
						catch(InputMismatchException f)
						{
							System.out.println("Sprobuj ponownie!");
							licytacja(1);
						}
					}
				}	
			}
		}
		
		
		
		
		
		
		
		
	}
	
	public final void wymianaKart(final BadugiGracz obecnyGracz)
    {
        System.out.print("Czy chcesz wymieniac karty?['T'|'N']: ");
        String odp = sc.next();
        if (odp.equals("T"))
        {
            dobierzKartyGraczowi(obecnyGracz.wybierzKartyDoWymiany(), obecnyGracz);
            System.out.println("Twoje karty po wymianie: " + obecnyGracz.pobierzKarty());
        }
        else 
        {
            System.out.println("!!!!!Nie wymieniasz kart.!!!!!");
        }
    }
	
	void wymiana(int numerWymiany)
	{
		for (Iterator<BadugiGracz> i = gracze.iterator(); i.hasNext();)
        {	
			BadugiGracz obecnyGracz = i.next();
			if (obecnyGracz == zaczynaGracz) { //gracz ktory zaczyna licytacje nie wymienia kart
				obecnyGracz = i.next();
			}
            if (obecnyGracz instanceof BadugiBot)
            {
                System.out.println("Ruch wykonuje Bot...");
               obecnyGracz.wybierzKartyDoWymiany();
                System.out.println("Bot wymienil " + obecnyGracz.pobierzIloscWymienionychKart() + " kart(y).");
                System.out.println("Nacisnij dowolny klawisz, zeby zakonczyc jego ruch: ");
                sc.nextLine();
            }
            else
            {
                System.out.println("");
                System.out.println("Teraz jest kolej: " + obecnyGracz);
                System.out.print("Prosze innych graczy o zamkniecie oczu. Nacinij dowolny klawisz jesli jestes gotowy.");
                sc.nextLine();
                symulujCzyszczenieEkranu();
                System.out.println("Twoje Karty: " +obecnyGracz.pobierzKarty());
                System.out.println("-----------------------------------------------");
                wymianaKart(obecnyGracz);
                sc.nextLine();
                System.out.print("Nacisnij dowolny klawisz, zeby zakonczyc kolejke: ");
                sc.nextLine();
                symulujCzyszczenieEkranu();
                System.out.println(obecnyGracz + " wymienil: " + obecnyGracz.pobierzIloscWymienionychKart() + " kart(y).");

            }

        }
	}
	
	void ktoZaczyna()
	{
		if (numerLicytacji == 1) 
		{
			for (ListIterator<BadugiGracz> i = gracze.listIterator(); i.hasNext(); )
			{
				BadugiGracz badanyGracz = i.next();
				if (badanyGracz.dealerButton == false && badanyGracz.smallBlind == false && badanyGracz.bigBlind == false)
				{
					zaczynaGracz = badanyGracz;
				}
			}
		}
		else if (numerLicytacji > 1 && numerLicytacji <= 4)
		{
			for (ListIterator<BadugiGracz> i = gracze.listIterator(); i.hasNext(); )
			{
				BadugiGracz badanyGracz = i.next();
				if (badanyGracz  == smallBlindGracz)
				{
					zaczynaGracz = badanyGracz;
				}
			}
		}
	}
	
	void ktoZwyciezyl()
	{
		BadugiGracz zwyciezca = ustalZwyciezce();
		System.out.println("---------------------------------------------------");
        System.out.println("Zwyciezyl: " + zwyciezca + " " + " uklad: " + zwyciezca.jakiUklad());
	}
	
	private void symulujCzyszczenieEkranu()
    {
        int i = 10;
        while (i-- > 0) {
			System.out.println("");
		}
    }
	
	void zakonczGre()
	{
		System.out.print("Nacisnij dowolny klawisz, zeby zakonczyc Gre: ");
        sc.nextLine();
        symulujCzyszczenieEkranu();
	}
	
	public final void rozgrywka() throws Exception
	{
		System.out.println("Rozgrywka sie zaczela");
		bank = 0;
		losujDealerButton();
        przypiszCiemne();
        rozdajZetony();
		wnoszenieZakladow();
		rozdajKarty();
		System.out.println("Karty rozdane");
		licytacja(1);
//		System.out.println("licytacja 1 skonczona");
		wymiana(1);
//		System.out.println("wymiana 1 skonczona");
		licytacja(2);
//		System.out.println("licytacja 2 skonczona");
    	wymiana(2);
//		System.out.println("wymiana 2 skonczona");
		licytacja(3);
//		System.out.println("licytacja 3 skonczona");
		wymiana(3);
//		System.out.println("wymiana 3 skonczona");
		licytacja(4);	
//		System.out.println("licytacja 4 skonczona");
		wyswietlStol();
//		System.out.println("stol wyswietlony");
    	ktoZwyciezyl();
//		System.out.println("zwyciezca podany");
//		podliczenieZetonow();
//		System.out.println("zetony podliczone");
		zakonczGre();	
	}
	
}
